﻿using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System;

using iPdf.Properties;
using Microsoft.Win32;

using Elegant.Ui;

namespace iPdf
{
    class FontColorGallery : Gallery
    {
        public FontColorGallery()
        {
            ((ISupportInitialize)this).BeginInit();

            try
            {
                ItemWidth = 28;
                ItemHeight = 28;
                ItemContentPadding = new Padding(2);

                InitializeColors();
                InitializePopupMenu();
            }
            finally
            {
                ((ISupportInitialize)this).EndInit();
            }

            ItemDrawMode = GalleryItemDrawMode.OwnerDraw;
            PopupResizeMode = GalleryPopupResizeMode.NoResize;
            PopupMinimumItemsInRowCount = 5;
            InteractionMode = GalleryInteractionMode.Action;
            SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
        }

        private readonly Elegant.Ui.Button AutomaticColorButton = new Elegant.Ui.Button();
        private readonly Elegant.Ui.Button MoreColorsButton = new Elegant.Ui.Button();

        private Bitmap _CurrentAutomaticColorButtonImage;
        private bool _CurrentAutomaticColorButtonImageValid;
        private static Color _automaticColor = SystemColors.WindowText;
        private Color _selectedColor = _automaticColor;
        private Color _hoveredColor = Color.Empty;

        public event EventHandler SelectedColorChanged;
        public event EventHandler HoveredColorChanged;
        public Color SelectedColor
        {
            get
            {
                if (_selectedColor == Color.Empty)
                {
                    return _automaticColor;
                }
                return _selectedColor;
            }
            set
            {
                _selectedColor = value;
            }
        }

        public Color HoveredColor
        {
            get
            {
                return _hoveredColor;
            }
        }


        private Bitmap AutomaticColorButtonImage
        {
            get
            {
                if (_CurrentAutomaticColorButtonImage != null && _CurrentAutomaticColorButtonImageValid)
                    return _CurrentAutomaticColorButtonImage;

                if (_CurrentAutomaticColorButtonImage != null)
                    _CurrentAutomaticColorButtonImage.Dispose();

                _CurrentAutomaticColorButtonImage = new Bitmap(iPdf.Properties.Resources.AutomaticColor16);

                Color autoColor = SystemColors.WindowText;
                for (int i = 0; i < _CurrentAutomaticColorButtonImage.Width; ++i)
                {
                    for (int j = 0; j < _CurrentAutomaticColorButtonImage.Height; ++j)
                    {
                        Color color = _CurrentAutomaticColorButtonImage.GetPixel(i, j);
                        if (color.A == 0)
                            _CurrentAutomaticColorButtonImage.SetPixel(i, j, autoColor);
                    }
                }

                _CurrentAutomaticColorButtonImageValid = true;

                return _CurrentAutomaticColorButtonImage;
            }
        }

        private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
        {
            _CurrentAutomaticColorButtonImageValid = false;
            AutomaticColorButton.DefaultSmallImage = AutomaticColorButtonImage;
        }

        private void InitializeColors()
        {
            if (Elegant.Ui.Control.IsInDesignMode)
            {
                return;
            }
            ItemCategories.Add(
                new GalleryItemCategory("Standard Colors", "Standard Colors", false, true, null));

            Items.AddRange(
                new object[]
                    {
                        new GalleryItem(Color.FromArgb(192, 0, 0), null, null, "Dark Red", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(255, 0, 0), null, null, "Red", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(255, 192, 0), null, null, "Orange", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(255, 255, 0), null, null, "Yellow", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(146, 208, 80), null, null, "Light Green", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(0, 176, 80), null, null, "Green", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(0, 176, 240), null, null, "Light Blue", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(0, 112, 192), null, null, "Blue", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(0, 32, 96), null, null, "Dark Blue", "Standard Colors"),
                        new GalleryItem(Color.FromArgb(112, 48, 160), null, null, "Purple", "Standard Colors")
                    }
                );
        }

        private void ChangeHoveredColor(Color newColor)
        {
            _hoveredColor = newColor;
            if (HoveredColorChanged != null)
            {
                HoveredColorChanged(this, new EventArgs());
            }
        }

        private void InitializePopupMenu()
        {
            AutomaticColorButton.Text = "Automatic";
            AutomaticColorButton.KeyTip = "A";
            AutomaticColorButton.Click += AutomaticColorButtonButton_Click;
            AutomaticColorButton.DefaultSmallImage = AutomaticColorButtonImage;
            AutomaticColorButton.MouseEnter += new EventHandler(
                delegate(object sender, EventArgs e)
                {
                    ChangeHoveredColor(_automaticColor);
                });
            AutomaticColorButton.MouseLeave += new EventHandler(
                delegate(object sender, EventArgs e)
                {
                    ChangeHoveredColor(Color.Empty);
                });

            MoreColorsButton.Text = "More Colors...";
            MoreColorsButton.KeyTip = "M";
            MoreColorsButton.Click += MoreColorsButton_Click;
            MoreColorsButton.DefaultSmallImage = iPdf.Properties.Resources.MoreColors16;

            Popup.Items.AddRange(
                new System.Windows.Forms.Control[]
                    {
                        AutomaticColorButton,
                        new Separator(),
                        MoreColorsButton
                    }
                    );
        }

        private void ChangeSelectedColor(Color newColor)
        {
            _selectedColor = newColor;
            if (SelectedColorChanged != null)
            {
                SelectedColorChanged(this, new EventArgs());
            }
        }

        protected override void OnHoveredItemChanged(GalleryHoveredItemChangedEventArgs e)
        {
            base.OnHoveredItemChanged(e);

            GalleryItem hoveredItem = this.HoveredItem as GalleryItem;
            ChangeHoveredColor(hoveredItem == null ? Color.Empty : (Color)hoveredItem.Data);
        }

        private void AutomaticColorButtonButton_Click(object sender, System.EventArgs e)
        {
            ChangeSelectedColor(_automaticColor);
        }

        private void MoreColorsButton_Click(object sender, System.EventArgs e)
        {
            Popup.Hide(false);

            ColorDialog colorDlg = new ColorDialog();
            colorDlg.FullOpen = true;

            DialogResult result = colorDlg.ShowDialog(TopLevelControl);
            if (result != DialogResult.OK)
                return;

            ChangeSelectedColor(colorDlg.Color);
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new IEnumerable DataSource
        {
            get { return base.DataSource; }
            set { base.DataSource = value; }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new ListWithEvents<object> Items
        {
            get { return base.Items; }
        }

        private readonly Color BorderColor = Color.FromArgb(197, 197, 197);
        private readonly Color HoveredOuterBorderColor = Color.FromArgb(242, 148, 54);
        private readonly Color HoveredInnerBorderColor = Color.FromArgb(255, 226, 148);

        protected override void OnDrawItem(GalleryDrawItemEventArgs e)
        {
            GalleryItem item = e.Item as GalleryItem;
            if (item == null || !(item.Data is Color))
            {
                base.OnDrawItem(e);
                return;
            }

            using (SolidBrush b = new SolidBrush((Color)item.Data))
            {
                e.Graphics.FillRectangle(b, e.ContentBounds);
            }

            Rectangle bounds = e.ContentBounds;

            if (e.Item == HoveredItem)
            {
                using (Pen p = new Pen(HoveredOuterBorderColor))
                {
                    bounds.Width -= 1;
                    bounds.Height -= 1;

                    e.Graphics.DrawRectangle(p, bounds);
                }

                using (Pen p = new Pen(HoveredInnerBorderColor))
                {
                    bounds.X += 1;
                    bounds.Y += 1;
                    bounds.Width -= 2;
                    bounds.Height -= 2;

                    e.Graphics.DrawRectangle(p, bounds);
                }
            }
            else
            {
                using (Pen p = new Pen(BorderColor))
                {
                    bounds.Width -= 1;
                    bounds.Height -= 1;

                    e.Graphics.DrawRectangle(p, bounds);
                }
            }
        }

        protected override void OnItemClick(GalleryItemClickEventArgs e)
        {
            base.OnItemClick(e);

            GalleryItem selectedItem = (GalleryItem)e.Item;

            ChangeSelectedColor( (Color)selectedItem.Data );
        }
    }
}